#include "BlockQueue.hpp"
#include "task.hpp"
#include <ctime>
int myAdd(int x, int y)
{
    return x + y;
}

void *Consumer(void *args)
{
    BlockQueue<Task> *bq = (BlockQueue<Task> *)args;
    while (true)
    {
        // int a = 0;
        Task t;
        bq->pop(&t);
        std::cout << pthread_self() << "Consumer:" << t.x_ << "+" << t.y_ << "=" << t() << std::endl;
        sleep(1);
    }
    return nullptr;
}
void *Product(void *args)
{
    BlockQueue<Task> *bq = (BlockQueue<Task> *)args;
    int a = 0;
    while (true)
    {
        int x = rand()%10 + 1;
        usleep(rand() % 1000);
        int y = rand() % 9;
        Task t(x,y,myAdd);
        bq->push(t);
        std::cout << pthread_self() << "Product:" << t.x_ << "+" << t.y_ << "= ?" << std::endl;
        a++;
        sleep(1);
    }
    return nullptr;
}

int main()
{
    srand((unsigned int)time(NULL) ^ getpid());
    BlockQueue<Task> *bq = new BlockQueue<Task>();
    pthread_t consumer[2], product[2];
    pthread_create(consumer, nullptr, Consumer, bq);
    pthread_create(consumer + 1, nullptr, Consumer, bq);
    pthread_create(product, nullptr, Product, bq);
    pthread_create(product + 2, nullptr, Product, bq);

    pthread_join(consumer[0], nullptr);
    pthread_join(consumer[1], nullptr);
    pthread_join(product[0], nullptr);
    pthread_join(product[1], nullptr);
    delete bq;
    return 0;
}